
#include "vector3f.h"

#ifndef MINFLOAT
  #define MINFLOAT  1.175494351E-38f
#endif

#ifndef MAXFLOAT
  #define MAXFLOAT  3.402823466E+38f
#endif

vector3f operator * ( float k, vector3f const& p )

{
  vector3f q;

  q.x = p.x * k;
  q.y = p.y * k;
  q.z = p.z * k;

  return q;
}


float distToEdge( vector3f v, vector3f head, vector3f tail )

{
  vector3f toV = v - tail;
  vector3f me = head - tail;
  float  dot = (toV * me) / (me * me);
  vector3f perp = toV - dot * me;

  if (dot < 0.15 || dot > 0.85)
    return MAXFLOAT;
  else
    return perp * perp;
}


vector3f vector3f::perp1()

{
  vector3f result(0,0,0);

  if (x == 0)
    if (y == 0 || z == 0)
      result.x = 1;     /* v = (0 0 z) or (0 y 0) */
    else {
      result.y = -z; /* v = (0 y z) */
      result.z = y;
    }
  else if (y == 0)
    if (z == 0)
      result.z = 1;     /* v = (x 0 0) */
    else {
      result.x = -z; /* v = (x 0 z) */
      result.z = x;
    }
  else {
    result.x = -y;   /* v = (x y z) or (x y 0) */
    result.y = x;
  }

  float lenRecip = 1.0f / (float)sqrt( result.x*result.x + result.y*result.y + result.z*result.z );
  result.x *= lenRecip;
  result.y *= lenRecip;
  result.z *= lenRecip;

  return result;
}


vector3f vector3f::perp2()

{
  vector3f result(0,0,0);

  if (x == 0)
    if (y == 0)
      result.y = 1;
    else if (z == 0)
      result.z = 1;
    else
      result.x = 1;
  else
    if (y == 0)
      result.y = 1;
    else if (z == 0)
      result.z = 1;
    else {
      result.x = x * z;
      result.y = y * z;
      result.z = - x*x - y*y;

      float lenRecip = 1.0f / (float)sqrt( result.x*result.x + result.y*result.y + result.z*result.z );
      result.x *= lenRecip;
      result.y *= lenRecip;
      result.z *= lenRecip;
    }

  return result;
}



ostream& operator << ( ostream& stream, vector3f const& p )

{
  stream << p.x << " " << p.y << " " << p.z;
  return stream;
}

istream& operator >> ( istream& stream, vector3f & p )

{
  stream >> p.x >> p.y >> p.z;
  return stream;
}


